<!--
 * @Description: 
 * @Version: V1.0.0
 * @Author: 周艳凯 484894717@qq.com
 * @Date: 2024-10-09 15:16:35
 * @LastEditors: 周艳凯 484894717@qq.com
 * @LastEditTime: 2024-11-11 17:59:10
 * @FilePath: index.vue
 * Copyright 2024 Marvin, All Rights Reserved. 
 * 2024-10-09 15:16:35
-->
<template>
  <div :class="cls">
    <div
      v-if="computedVisible"
      class="arco-trigger-mask"
      @click.stop.prevent="show"
    ></div>
    <view class="arco-trigger-target" @click="show">
      <slot></slot>
    </view>

    <div class="arco-trigger-popup" :style="popupStyle">
      <aTransition :duration="300" :show="computedVisible" appear name="fade">
        <div class="arco-trigger-popup-wrapper">
          <div class="arco-trigger-content arco-popover-popup-content">
            <slot name="content">{{ content }}</slot>
          </div>
          <div
            :style="arrow_Style"
            class="arco-trigger-arrow arco-popover-popup-arrow"
          ></div>
        </div>
      </aTransition>
    </div>

    <!-- <div
      v-show="computedVisible"
      class="arco-trigger-popup"
      :style="popupStyle"
    >
      <div class="arco-trigger-popup-wrapper">
        <div class="arco-trigger-content arco-popover-popup-content">
          <slot name="content">{{ content }}</slot>
        </div>
        <div
          :style="arrow_Style"
          class="arco-trigger-arrow arco-popover-popup-arrow"
        ></div>
      </div>
    </div> -->
  </div>
</template>

<script lang="ts">
import { TriggerPosition } from "@/ArcoUni/utils/interface";
import { getRect } from "@/ArcoUni/utils/layout";
import { getArrowStyle, getPopupStyle } from "./utils";
import aTransition from "../arco-transition/index.vue";
import {
  computed,
  CSSProperties,
  defineComponent,
  getCurrentInstance,
  nextTick,
  onMounted,
  PropType,
  ref,
} from "vue";
import { TriggerPopupTranslate } from "./interface";
const icon = defineComponent({
  name: "Card",
  components: {
    aTransition,
  },
  options: {
    // 虚拟化节点
    virtualHost: true,
  },
  props: {
    size: {
      type: String,
      default: "medium",
    },
    bordered: {
      type: Boolean,
      default: true,
    },
    content: {
      type: String,
      default: "",
    },
    /**
     * @zh 弹出位置
     * @en Popup position
     * @values 'top','tl','tr','bottom','bl','br','left','lt','lb','right','rt','rb'
     */
    position: {
      type: String as PropType<TriggerPosition>,
      default: "bottom",
    },
    /**
     * @zh 弹出框的偏移量（弹出框距离触发器的偏移距离）
     * @en The offset of the popup (the offset distance of the popup from the trigger)
     */
    popupOffset: {
      type: Number,
      default: 10,
    },
    /**
     * @zh 弹出框的移动距离
     * @en The moving distance of the popup
     */
    popupTranslate: {
      type: [Array, Object] as PropType<TriggerPopupTranslate>,
    },
    /**
     * @zh 弹出框是否可见
     * @en Whether the popup is visible
     * @vModel
     */
    popupVisible: {
      type: Boolean,
      default: undefined,
    },
    /**
     * @zh 弹出框默认是否可见（非受控模式）
     * @en Whether the popup is visible by default (uncontrolled mode)
     */
    defaultPopupVisible: {
      type: Boolean,
      default: false,
    },
    /**
     * @zh 弹出框箭头的样式
     * @en The style of the popup arrow
     */
    arrowStyle: {
      type: Object as PropType<CSSProperties>,
    },
  },
  emits: ["update:popupVisible", "popupVisibleChange", "show", "hide"],
  setup(props, { emit }) {
    const prefixCls = "arco-popover";
    const instance = getCurrentInstance() as any;

    // 弹出框的挂载容器
    const popupContainer = ref({});
    const triggerContainer = ref({});

    const popupStyle = ref<CSSProperties>({});
    const arrow_Style = ref<CSSProperties>({});

    const popupVisible = ref(props.defaultPopupVisible);

    const computedVisible = computed(
      () => props.popupVisible ?? popupVisible.value,
    );

    const showPopover = ref<boolean>(false); // 控制popover显隐

    const classNames = computed(() => {
      return [`${prefixCls}-popup`, `${prefixCls}-position--${props.position}`];
    });

    async function ges() {
      await getRect(".arco-trigger-target", false, instance).then((rects) => {
        triggerContainer.value = rects;
      });
    }

    async function gess() {
      await getRect(".arco-trigger-popup", false, instance).then((rects) => {
        popupContainer.value = rects;
      });
    }

    onMounted(() => {
      ges();
      gess();
    });

    const updatePopupStyle = async () => {
      // 挂载容器
      const containerRect = await getTriggerRect();
      const popupRect = await getPopupRect();
      const { style, position } = getPopupStyle(
        props.position,
        containerRect as any,
        popupRect as any,
        {
          offset: props.popupOffset,
          translate: props.popupTranslate,
        },
      );

      popupStyle.value = style;

      nextTick(async () => {
        const popupContainer = await getPopupRect();
        arrow_Style.value = getArrowStyle(
          position,
          containerRect as any,
          popupContainer as any,
          {
            customStyle: props.arrowStyle,
          },
        );
      });
    };

    const cls = computed(() => {
      return [`${prefixCls}-popup`, `${prefixCls}-position--${props.position}`];
    });

    async function getTriggerRect() {
      const rects = await getRect(".arco-trigger-target", false, instance);
      return rects;
    }
    async function getPopupRect() {
      const rects = await getRect(".arco-trigger-popup", false, instance);
      return rects;
    }

    const changeVisible = (visible: boolean) => {
      if (visible === computedVisible.value) {
        return;
      }
      const update = () => {
        popupVisible.value = visible;
        emit("update:popupVisible", visible);
        emit("popupVisibleChange", visible);
        if (visible) {
          nextTick(() => {
            updatePopupStyle();
          });
        }
      };
      update();
    };

    function show() {
      changeVisible(!computedVisible.value);
    }

    return {
      cls,
      classNames,
      showPopover,
      popupStyle,
      show,
      arrow_Style,
      computedVisible,
    };
  },
});
export default icon;
</script>

<style scoped lang="less"></style>
